﻿using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

namespace AutoUpdate
{
    class FileUpdater
    {
        class VersionResponse
        {
            public int code;
            public Version data;
        }

        internal class Version
        {
            public string number;
            public string url;
            //使用title作为各浏览器支持版本的详情
            //格式为：google=94.0#edge=94.0#360=86.0#firefox=93.0
            public string title;
        }

        static string baseUrl = "http://tianshiweidi.com";

        internal async Task<Version> getLatestVersion()
        {
            HttpResponseMessage response;
            VersionResponse versionResponse;
            try
            {
                response = await new HttpClient().GetAsync(baseUrl + "/api/app/version/lasted");
            }
            catch (HttpRequestException e)
            {
                throw new Exception("网络请求异常:" + e.InnerException.Message);
            }

            if (response.StatusCode != HttpStatusCode.OK)
            {
                throw new Exception("网络请求异常,状态码：" + (int)response.StatusCode);
            }

            string result = await response.Content.ReadAsStringAsync();
            try
            {
                versionResponse = JsonConvert.DeserializeObject<VersionResponse>(result);
            }
            catch (Exception)
            {
                throw new Exception("数据返回格式不一致，解析数据失败");
            }
            return versionResponse.data;
        }

        internal async Task<string> download(string url, DownloadProgressChangedEventHandler progressHandler)
        {
            WebClient client = new WebClient();
            string fileNewName = Guid.NewGuid() + ".zip";
            string saveDir = Path.GetTempPath();
            string filePath = Path.Combine(saveDir, fileNewName);
            client.DownloadProgressChanged += progressHandler;
            await client.DownloadFileTaskAsync(new Uri(baseUrl + url), filePath);
            return filePath;
        }

        internal string unzip(string zipPath)
        {
            string dir = Path.GetTempPath() + "\\" + Guid.NewGuid();
            Directory.CreateDirectory(dir);
            ZipFile.ExtractToDirectory(zipPath, dir);
            new FileInfo(zipPath).Delete();
            return dir;
        }

        internal void killProcess()
        {
            ArrayList procNames = new ArrayList() { "AngleExpress", "360driver", "msedgedriver", "chromedriver", "geckodriver" };
            Process[] processes = Process.GetProcesses();
            foreach (Process pr in processes)
            {
                if (procNames.Contains(pr.ProcessName))
                {
                    pr.Kill();
                }
            }
        }

        internal void replaceFiles(string newFileDir, string oldFileDir)
        {
            var newFileInfos = new DirectoryInfo(newFileDir).GetFileSystemInfos();
            IEnumerable<string> newFileNames = newFileInfos.Select(newFile => newFile.Name);

            var oldFileInfos = new DirectoryInfo(oldFileDir).GetFileSystemInfos();
            var willRemoveFiles = oldFileInfos.Where(oldFile =>
                 newFileNames.Contains(oldFile.Name)
            );
            foreach (FileSystemInfo fsi in willRemoveFiles)
            {
                if (fsi.Attributes == FileAttributes.Directory)
                {
                    var dirInfo = (DirectoryInfo)fsi;
                    dirInfo.Delete(true);
                }
                else
                    fsi.Delete();
            }

            foreach (FileSystemInfo fsi in newFileInfos)
            {
                if (fsi.Attributes == FileAttributes.Directory)
                {
                    var dir = (DirectoryInfo)fsi;
                    string destPath = Path.Combine(oldFileDir, dir.Name);
                    dir.MoveTo(destPath);
                }
                else
                {
                    var file = (FileInfo)fsi;
                    string destPath = Path.Combine(oldFileDir, file.Name);
                    file.MoveTo(destPath);
                }
            }
        }

    }
}
